package com.rongke.web.paymentrefund;

import org.dom4j.DocumentException;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;


import java.io.*;
import java.net.HttpURLConnection;
import java.net.URL;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

/**
 * Created by Administrator on 2017/7/24.
 * 退款查询接口
 */
public class Query {
    public static void main(String[] args){
        String s = query();
        System.out.println("返回结果："+s);
    }

    private static String query() {
        //请求地址
        String url = "https://Query.heepay.com/API/Payment/PaymentRefundQuery.aspx";
        //请求参数
        String agent_bill_id = "7551000001201707241100058782";          //商户系统内部的定单号
        String agent_id = "1664502";       //商户编号
        String version = "1";               //当前接口版本号
        String agent_refund_bill_no = "7551000001201707241000058783";   //商户系统内部的退款单号
        String sign_type = "MD5";           //商户系统内部的退款单号
        String key = "1C3A345D4F1E48B7A02B90AC";                        //签名密钥
        String sign = "";                   //签名结果

        //组织签名串
        StringBuilder sign_sb = new StringBuilder();
        sign_sb.append("agent_bill_id") .append("=").append(agent_bill_id).append("&")
                .append("agent_id")      .append("=").append(agent_id)     .append("&")
                .append("key")            .append("=").append(key)          .append("&")
                .append("version")       .append("=").append(version);
        System.out.println("签名参数："+sign_sb.toString());
        sign = MD5en(sign_sb.toString().toLowerCase());
        System.out.println("签名结果："+sign);
        //请求参数
        StringBuilder requestParams = new StringBuilder();
        requestParams.append("agent_bill_id") .append("=").append(agent_bill_id)            .append("&")
                .append("agent_id")            .append("=").append(agent_id)                 .append("&")
                .append("version")             .append("=").append(version)                  .append("&")
                .append("agent_refund_bill_no").append("=").append(agent_refund_bill_no)   .append("&")
                .append("sign_type")           .append("=").append(sign_type)				   .append("&")
                .append("sign")                 .append("=").append(sign);
        System.out.println("请求参数："+requestParams.toString());
        String ret = sendPost(url,requestParams.toString());
        //解析返回的参数
        //判断是否请求成功，成功解析xml，   失败直接返回失败原因
        if(!ret.contains("<detail_data>")){
            return ret ;
        }

        //验证返回的sign
        try {
            //解析XML形式的文本,得到document对象.
            org.dom4j.Document document = DocumentHelper.parseText(ret);
            //1.获取文档的根节点.
            Element rootElm = document.getRootElement();
            //2.取得某节点的单个子节点.
            Element m_agent_id = rootElm.element("agent_id");
            Element m_detail_data = rootElm.element("detail_data");
            Element m_ret_code = rootElm.element("ret_code");
            Element m_ret_msg = rootElm.element("ret_msg");
            Element m_sign = rootElm.element("sign");

            //3.取得节点的文字
            String y_agent_id = m_agent_id.getText();

            //detail_data参数用xml解析，会导致\r丢失，所以将\n换成\r\n
            String y_detail_data = m_detail_data.getText().replaceAll("\n","\r\n");

            String y_ret_code = m_ret_code.getText();
            String y_ret_msg = m_ret_msg.getText();
            String y_sign = m_sign.getText();

            System.out.println(y_agent_id);
            System.out.println(y_detail_data);
            System.out.println(y_ret_code);
            System.out.println(y_ret_msg);
            System.out.println(y_sign);


            String sign1 = "agent_id="+y_agent_id+
                    "&detail_data="+y_detail_data+
                    "&key="+key+
                    "&ret_code="+y_ret_code+
                    "&ret_msg="+y_ret_msg;
            sign1 = sign1.toLowerCase();
            sign1 = MD5en(sign1);
            //判断验证签名是否成功
            if(y_sign.equals(sign1)){
                return y_detail_data;
            }else {
                return "签名验证失败";
            }
        } catch (DocumentException e) {
            e.printStackTrace();
        }





        return ret;
    }


    /**
     * 向指定 URL 发送POST方法的请求
     *
     * @param curl
     *            发送请求的 URL
     * @param param
     *            请求参数，请求参数应该是 name1=value1&name2=value2 的形式。
     * @return 所代表远程资源的响应结果
     */
    public static String sendPost(String curl, String param) {
        try {
            //创建连接
            URL url = new URL(curl);
            HttpURLConnection connection = (HttpURLConnection) url
                    .openConnection();
            connection.setDoOutput(true);
            connection.setDoInput(true);
            connection.setRequestMethod("POST");
            connection.setUseCaches(false);
            connection.setInstanceFollowRedirects(true);
            connection.setRequestProperty("Content-Type",
                    "application/x-www-form-urlencoded");

            connection.connect();

            //POST请求
            DataOutputStream out = new DataOutputStream(
                    connection.getOutputStream());

            out.writeBytes(param);
            out.flush();
            out.close();

            //读取响应
            DataInputStream in = new DataInputStream(connection.getInputStream());
            ByteArrayOutputStream buffer = new ByteArrayOutputStream();
            int c;
            while ((c = in.read()) >= 0) {
                buffer.write(c);
            }
            buffer.close();
            byte[] bytes = buffer.toByteArray();
            String rev = new String(bytes, "GBK");
            return rev;
        } catch (IOException e) {
            e.printStackTrace();
            return "Post请求异常";
        }
    }

    /**
     * MD5加密
     * @param str 需要加密的值
     * @return 加密完成的值(小写)
     */
    public static String MD5en(String str){
        String re_md5 = new String();
        try {
            MessageDigest md = MessageDigest.getInstance("MD5");
            md.update(str.getBytes());
            byte b[] = md.digest();

            int i;

            StringBuffer buf = new StringBuffer("");
            for (int offset = 0; offset < b.length; offset++) {
                i = b[offset];
                if (i < 0)
                    i += 256;
                if (i < 16)
                    buf.append("0");
                buf.append(Integer.toHexString(i));
            }

            re_md5 = buf.toString();

        } catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        }
        return re_md5;
    }
}
